/* eslint-disable react/display-name */
/*
 * @Author: shawnxiao
 * @Date: 2021-04-27 17:38:26
 * @LastEditTime: 2021-11-17 18:39:55
 * @FilePath: /gatt-react/src/components/DynamicFormReader/index.tsx
 */
import React, { useEffect, useImperativeHandle, Fragment } from 'react'
import { Form, Button, Collapse, Space } from 'antd'
import {uuid} from '@/common/utils'
import FormFieldRender from './FormFieldRender'
import './index.less'

const { Panel } = Collapse

type inputType = 'input' | 'inputNumber' | 'search' | 'textArea' | 'password' | 'datePicker' | 'dateRangePicker' | 'timePicker' | 'timeRangePicker' | 'select' | 'cascader' | 'checkbox' | 'checkboxGroup' | 'radio' | 'radioGroup' | 'treeSelect'
/**
 * 配置 数据录入的 类型
 */
export type configType = {
  /* 该 输入框所占的 栅栏数 */
  span: number
  /* Form.item 的 label 值 */
  title: string
  /* Form.item 的 name 值 */
  key: string
  /* Form.item 的 rules 值 */
  rules?: any[]
  /* 录入数据的 提示 */
  placeholder: string
  /* 录入数据的类型 */
  type: inputType,
  /* Select|Cascader 类型的 options 值 */
  options?: any[]
  /* Form.item 的 其它属性 */
  [key: string]: any
}

type configsProps = {
  title?: string
  type?: string
  important?: boolean
  list: configType[]
}

interface propsForm{
  configs: configsProps[]
  cRef: any,
  formData?: any
  noAction?: boolean // 未传默认有操作按钮
  layout?: string // 未传默认有操作按钮
  styleCollapse?: any // Collapse自定义样式
  btnTxt?: string // 按钮文案
  btnCancelTxt?: string // 按钮文案
  btnSize?: string // 按钮大小
  finishToSave?: Function // 保存函数
  spaceProps?: any // 按钮容器space设置项
}

const DynamicFormReader = ({configs, cRef, formData, noAction, layout = 'vertical', btnTxt = '提交', btnCancelTxt = '重置', styleCollapse = {padding: '10px', backgroundColor: '#fff', border: 'none'}, finishToSave = () => {}, btnSize = 'small', spaceProps}: propsForm | any) => {
  // 通过Form.useForm对表单数据域进行交互。useForm是React Hooks的实现，只能用于函数组件
  const [formRef] = Form.useForm()
  // cRef就是父组件传过来的ref
  useImperativeHandle(cRef, () => ({
    // getForm就是暴露给父组件的方法
    getForm: () => formRef
  }))

  // const tailLayout = {
  //   wrapperCol: { offset: 4, span: 16 }
  // }

  // 对动态表单动态交互场景下产生的数据赋值操作（转化成value,label键值对形式）
  function formatFormToValLabel(values:Object){
    const form = {}
    // 以form_+hash作为取值
    const hash = 'form_' + window.location.hash
    const strJson = window.sessionStorage.getItem(hash)
    const formSessionStorage = JSON.parse(strJson as string)
    Object.keys(values).forEach((key:any) => {
      if (values[key]?._isAMomentObject){
        // 日期时间moment对象
        form[key] = values[key].format('YYYY-MM-DD')
      } else {
        if (formSessionStorage?.key === key) {
          const temp:any[] = []
          // 存在动态交互场景下产生的数据赋值操作（转化成value,label键值对形式）
          if (formSessionStorage?.value?.length) {
            formSessionStorage.value.forEach((item:any) => {
              temp.push({
                type: 'cascader',
                value: item,
                label: formSessionStorage?.selectedOptions?.find((v:any) => v?.value === item)?.label
              })
            })
          }
          form[key] = [...temp]
        } else {
          form[key] = values[key]
        }
      }
    })
    return {...form}
  }

  // 若有正则验证，则在所有的正则校验都通过后用来获取输入的数据，若没有正则校验，则直接获取输入的数据
  const onFinish = (values:Object) => {
    const form = formatFormToValLabel(values)
    finishToSave(form, values)
  }

  // 重置要配合着const [form] = Form.useForm()以及form={form}
  const onReset = () => {
    formRef.resetFields()
  }

  // form表单的回显
  useEffect(() => {
    formRef.setFieldsValue(formData)
  }, [])

  return (
    <div className="formCom-box">
      <Form name="basic" layout={layout} form={formRef} onFinish={onFinish}>
        {
          configs?.length ? (
          <Collapse
            defaultActiveKey={configs.map((type:any) => type.type) as string[]}
            style={styleCollapse}
          >
          {
            configs.map((item:any) => {
              return (
                <Fragment key={item?.type || uuid(5)}>
                {
                  !item?.noCollapse ? (
                    <Panel header={item?.title} key={item?.type || uuid(5)}>
                      <FormFieldRender formRef={formRef} columns={item?.list} gutter={item?.gutter || [20, 20]} key={item?.type || uuid(6)}/>
                    </Panel>
                  ) : <FormFieldRender formRef={formRef} columns={item?.list} gutter={item?.gutter || [20, 20]} key={item?.type || uuid(6)}/>
                }
                </Fragment>
              )
            })
          }
          </Collapse>) : null
        }
        {
          !noAction ? (
            <Space {...spaceProps} className="formCom-box-space">
              <Button type="primary" htmlType="submit" size={btnSize} style={{marginRight: '20px'}}>{btnTxt}</Button>
              <Button htmlType="button" onClick={onReset} size={btnSize}>{btnCancelTxt}</Button>
            </Space>
          ) : null
        }
      </Form>
    </div>
  )
}

export default DynamicFormReader
